part of 'page.dart';

class _CollectionSingleLexicalItemPageWloc
    extends StatefulWloc<_CollectionSingleLexicalItemPageWlocState, CollectionSingleLexicalItemPage>
    with CardWlocMixin {
  late final bloc.CollectionSingleLexicalItemPageBloc _bloc;

  @override
  _CollectionSingleLexicalItemPageWlocState get initialState {
    return _CollectionSingleLexicalItemPageWlocStateFactory().create(
      blocState: _bloc.state,
    );
  }

  void onPronunciationButtonPressed() {
    _bloc.requestLexicalItemPronunciation();
  }

  void onUseCasePronunciationButtonPressed(LexicalItemUseCase useCase) {
    _bloc.requestLexicalItemUseCasePronunciation(
      lexicalItemUseCase: useCase,
    );
  }

  void onPronunciationCautionButtonPressed() {
    showPronunciationCautionDialog(
      context: context,
    );
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // all card action dialog
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void showCardActions() async {
    final cardAction = await showAppActionDialog<CardAction>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          actions: state.cardActions.map((cardAction) {
            return switch (cardAction) {
              MistakeReportCardAction() => buildMistakeReportCardAction(
                cardAction: cardAction,
                context: context,
              ),
              ProgressResetCardAction() => buildProgressResetCardAction(
                cardAction: cardAction,
                context: context,
              ),
              MarkAsKnownCardAction() => buildMarkAsKnownCardAction(
                cardAction: cardAction,
                context: context,
              ),
              MarkAsCompletelyLearnedCardAction() => buildMarkAsCompletelyLearnedCardAction(
                cardAction: cardAction,
                context: context,
              ),
              AdditionToLearningQueueCardAction() => buildAdditionToLearningQueueCardAction(
                cardAction: cardAction,
                context: context,
              ),
              RemovalFromLearningQueueCardAction() => buildRemovalFromLearningQueueCardAction(
                cardAction: cardAction,
                context: context,
              ),
              ReturnToLearningCardAction() => buildReturnToLearningCardAction(
                cardAction: cardAction,
                context: context,
              ),
              AdditionToCustomCollectionCardAction() => buildAdditionToCustomCollectionCardAction(
                cardAction: cardAction,
                context: context,
              ),
              ExclusionFromLearningCardAction() => buildExclusionFromLearningCardAction(
                cardAction: cardAction,
                context: context,
              ),
              EditingCardAction() => buildEditingCardAction(
                cardAction: cardAction,
                context: context,
              ),
              RemovalCardAction() => _buildRemovalCardAction(
                cardAction: cardAction,
                context: context,
              ),
              _ => throw UnimplementedError(),
            };
          }).toList(),
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    // ignore: use_build_context_synchronously
    if (!context.mounted) {
      return;
    }

    switch (cardAction) {
      case MistakeReportCardAction():
        showMistakeReportDialog(
          context: context,
          cardAction: cardAction,
          onReportThroughTelegram: _onMistakeReportThroughTelegramCardActionPressed,
          onReportByEmail: () {
            _onMistakeReportByEmailCardActionPressed(
              cardAction: cardAction,
            );
          },
        );

      case ProgressResetCardAction():
        _onProgressResetCardActionPressed();

      case MarkAsKnownCardAction():
        _onMarkAsKnownCardActionPressed(
          cardAction: cardAction,
        );

      case MarkAsCompletelyLearnedCardAction():
        _onMarkAsCompletelyLearnedCardActionPressed(
          cardAction: cardAction,
        );

      case AdditionToLearningQueueCardAction():
        _onAdditionToLearningQueueCardActionPressed(
          cardAction: cardAction,
        );

      case RemovalFromLearningQueueCardAction():
        _onRemovalFromLearningQueueCardActionPressed();

      case ReturnToLearningCardAction():
        _onReturnToLearningCardActionPressed();

      case AdditionToCustomCollectionCardAction():
        _onAdditionToCustomCollectionCardActionPressed(
          cardAction: cardAction,
        );

      case EditingCardAction():
        _showEditingDialog();

      case ExclusionFromLearningCardAction():
        _onExclusionFromLearningCardActionPressed(
          cardAction: cardAction,
        );

      case RemovalCardAction():
        _showImplicitRemovalDialog(
          cardAction: cardAction,
        );
    }
  }

  void _onMistakeReportByEmailCardActionPressed({
    required MistakeReportCardAction cardAction,
  }) {
    final availableMailApps = cardAction.availableEmailApps;

    if (availableMailApps.isEmpty) {
      _bloc.requestMistakeReportByEmail(
        emailApp: null,
      );
    } else if (availableMailApps.length == 1) {
      _bloc.requestMistakeReportByEmail(
        emailApp: availableMailApps.first,
      );
    } else {
      showMailAppChoosingDialog(
        context: context,
        availableMailApps: availableMailApps,
        onEmailAppChosen: (chosenMailApp) {
          _bloc.requestMistakeReportByEmail(
            emailApp: chosenMailApp,
          );
        },
      );
    }
  }

  void _onMistakeReportThroughTelegramCardActionPressed() {
    _bloc.requestMistakeReportThroughTelegram();
  }

  void _onProgressResetCardActionPressed() {
    _bloc.requestProgressReset();
  }

  void _onMarkAsKnownCardActionPressed({
    required MarkAsKnownCardAction cardAction,
  }) {
    _bloc.requestMarkLexicalItemAsKnown();
  }

  void _onMarkAsCompletelyLearnedCardActionPressed({
    required MarkAsCompletelyLearnedCardAction cardAction,
  }) {
    _bloc.requestMarkLexicalItemAsCompletelyLearned();
  }

  void _onAdditionToLearningQueueCardActionPressed({
    required AdditionToLearningQueueCardAction cardAction,
  }) {
    _bloc.requestLexicalItemAdditionToLearningQueue();
  }

  void _onRemovalFromLearningQueueCardActionPressed() {
    _bloc.requestLexicalItemRemovalFromLearningQueue();
  }

  void _onReturnToLearningCardActionPressed() {
    _bloc.requestLexicalItemReturnToLearning();
  }

  void _onAdditionToCustomCollectionCardActionPressed({
    required AdditionToCustomCollectionCardAction cardAction,
  }) {
    if (cardAction.collectionInfos.length == 1) {
      final collectionInfo = cardAction.collectionInfos.first;
      final customCollectionId = collectionInfo.customCollection.id;

      _onAdditionToSingleCollectionCardActionPressed(
        customCollectionId: customCollectionId,
        cardAction: cardAction,
      );
    } else {
      showAdditionToCollectionDialog(
        context: context,
        cardAction: cardAction,
        onAddToCustomCollection: (customCollectionId) {
          _onAdditionToSingleCollectionCardActionPressed(
            customCollectionId: customCollectionId,
            cardAction: cardAction,
          );
        },
      );
    }
  }

  void _onAdditionToSingleCollectionCardActionPressed({
    required String customCollectionId,
    required AdditionToCustomCollectionCardAction cardAction,
  }) {
    _bloc.requestLexicalItemAdditionToCustomCollection(
      customCollectionId: customCollectionId,
    );
  }

  void _onExclusionFromLearningCardActionPressed({
    required ExclusionFromLearningCardAction cardAction,
  }) {
    _bloc.requestLexicalItemExclusionFromLearning();
  }

  void _showEditingDialog() {
    showAppFullscreenModal(
      enableDrag: false,
      builder: (context) {
        return CustomLexicalItemEditingPage(
          customLexicalItemId: widget.pageModel.lexicalItemId,
        );
      },
    );
  }

  AppActionDialogAction _buildRemovalCardAction({
    required RemovalCardAction cardAction,
    required BuildContext context,
  }) {
    final String title;

    if (cardAction.removalModes.length == 1 &&
        cardAction.removalModes.first == LexicalItemRemovalMode.implicitRemoval) {
      title = CollectionSingleLexicalItemPageTranslation.of(context)
          .buildRemovalFromCollectionCardActionTitle(
        collectionTitle: cardAction.collectionTitle,
        collectionFolderTitle: cardAction.collectionFolderTitle,
      );
    } else {
      title = CollectionSingleLexicalItemPageTranslation.of(context).removalCardActionTitle;
    }

    return AppActionDialogAction(
      title: title,
      isDestructiveAction: true,
      onPressed: () {
        Navigator.of(context).pop(cardAction);
      },
    );
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // removal dialogs
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void _showImplicitRemovalDialog({
    required RemovalCardAction cardAction,
  }) async {
    final removalMode = await showAppActionDialog<LexicalItemRemovalMode>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message:
              CollectionSingleLexicalItemPageTranslation.of(context).implicitRemovalDialogTitle,
          actions: [
            AppActionDialogAction(
              title: CollectionSingleLexicalItemPageTranslation.of(context)
                  .buildImplicitRemovalDialogRemovalAnswer(
                collectionTitle: cardAction.collectionTitle,
                collectionFolderTitle: cardAction.collectionFolderTitle,
              ),
              isDestructiveAction: true,
              onPressed: () {
                Navigator.of(context).pop(LexicalItemRemovalMode.implicitRemoval);
              },
            ),
            if (cardAction.removalModes.length > 1)
              AppActionDialogAction(
                title: CollectionSingleLexicalItemPageTranslation.of(context)
                    .buildImplicitRemovalDialogDeletionAnswer(
                  collectionTitle: cardAction.collectionTitle,
                  collectionFolderTitle: cardAction.collectionFolderTitle,
                ),
                isDestructiveAction: true,
                onPressed: () {
                  Navigator.of(context).pop(LexicalItemRemovalMode.implicitDeletion);
                },
              ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (removalMode != null) {
      _bloc.requestLexicalItemRemoval(
        removalMode: removalMode,
      );
    }
  }

  void _showExplicitRemovalDialog() async {
    final removalAction = state.cardActions.firstWhere((cardAction) {
      return cardAction is RemovalCardAction;
    }) as RemovalCardAction;

    final removalMode = await showAppActionDialog<LexicalItemRemovalMode>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message:
              CollectionSingleLexicalItemPageTranslation.of(context).explicitRemovalDialogTitle,
          actions: [
            AppActionDialogAction(
              title: CollectionSingleLexicalItemPageTranslation.of(context)
                  .buildExplicitRemovalDialogRemovalAnswer(
                collectionTitle: removalAction.collectionTitle,
                collectionFolderTitle: removalAction.collectionFolderTitle,
              ),
              isDestructiveAction: true,
              onPressed: () {
                Navigator.of(context).pop(LexicalItemRemovalMode.explicitRemoval);
              },
            ),
            AppActionDialogAction(
              title: CollectionSingleLexicalItemPageTranslation.of(context)
                  .explicitRemovalDialogDeletionAnswer,
              isDestructiveAction: true,
              onPressed: () {
                Navigator.of(context).pop(LexicalItemRemovalMode.explicitDeletion);
              },
            ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (removalMode != null) {
      _bloc.requestLexicalItemRemoval(
        removalMode: removalMode,
      );
    }
  }

  // </editor-fold>

  void _onBlocStateChanged(bloc.CollectionSingleLexicalItemPageBlocState blocState) {
    final updatedState = _CollectionSingleLexicalItemPageWlocStateFactory().create(
      blocState: blocState,
    );

    emit(updatedState);

    if (blocState.explicitRemovalDialogShown) {
      _showExplicitRemovalDialog();
    }
  }

  @override
  void initState() {
    super.initState();

    _bloc = bloc.CollectionSingleLexicalItemPageBloc(
      pageModel: widget.pageModel,
      learningContentBloc: core_di.sl(),
      userInfoBloc: core_di.sl(),
      settingsBloc: core_di.sl(),
      overlayBloc: core_di.sl(),
      emailBloc: core_di.sl(),
      urlLauncherBloc: core_di.sl(),
      collectionNavigatorBloc: core_di.sl(),
      purchaseFlowDisplayBloc: core_di.sl(),
      getInitialData: collection_single_lexical_item_page_di.sl(),
      initialize: collection_single_lexical_item_page_di.sl(),
      addLexicalItemToCustomCollection: collection_single_lexical_item_page_di.sl(),
      addLexicalItemToLearningQueue: collection_single_lexical_item_page_di.sl(),
      excludeLexicalItemFromLearning: collection_single_lexical_item_page_di.sl(),
      handleAvailableEmailAppOuterUpdate: collection_single_lexical_item_page_di.sl(),
      handleLearningContentOuterUpdate: collection_single_lexical_item_page_di.sl(),
      handlePremiumAccessStatusOuterUpdate: collection_single_lexical_item_page_di.sl(),
      markLexicalItemAsCompletelyLearned: collection_single_lexical_item_page_di.sl(),
      markLexicalItemAsKnown: collection_single_lexical_item_page_di.sl(),
      pronounceLexicalItem: collection_single_lexical_item_page_di.sl(),
      pronounceLexicalItemUseCase: collection_single_lexical_item_page_di.sl(),
      removeLexicalItem: collection_single_lexical_item_page_di.sl(),
      removeLexicalItemFromLearningQueue: collection_single_lexical_item_page_di.sl(),
      reportLexicalItemMistakeByEmail: collection_single_lexical_item_page_di.sl(),
      resetLexicalItemProgress: collection_single_lexical_item_page_di.sl(),
      returnLexicalItemToLearning: collection_single_lexical_item_page_di.sl(),
      handleImageSettingsOuterUpdate: collection_single_lexical_item_page_di.sl(),
      handleCachedImagePathMapOuterUpdate: collection_single_lexical_item_page_di.sl(),
      handleDialectOuterUpdate: collection_single_lexical_item_page_di.sl(),
    );

    _bloc.stream.listen(_onBlocStateChanged);
  }

  @override
  void dispose() {
    _bloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _CollectionSingleLexicalItemPageView(
      wloc: this,
    );
  }
}
